package com.yonyou.cyxdms.sysAuth.service.service.notification.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonyou.cyx.framework.bean.dto.framework.RestResultResponse;
import com.yonyou.cyx.framework.service.http.HttpRequestService;
import com.yonyou.cyx.framework.util.bean.ApplicationContextHelper;
import com.yonyou.cyx.function.bean.dto.http.RestServiceRequestDto;
import com.yonyou.cyx.function.bean.dto.http.RestServiceResponseDto;
import com.yonyou.cyx.function.exception.DALException;
import com.yonyou.cyx.function.exception.DMSAuthException;
import com.yonyou.cyx.function.utils.bean.BeanMapperUtil;
import com.yonyou.cyx.function.utils.common.DateUtil;
import com.yonyou.cyx.function.utils.common.StringUtils;
import com.yonyou.cyxdms.framework.bean.dto.user_info.LoginInfoDto;
import com.yonyou.cyxdms.sysAuth.service.constants.CommonConstants;
import com.yonyou.cyxdms.sysAuth.service.constants.SysAuthCommonConstants;
import com.yonyou.cyxdms.sysAuth.service.dto.ExtraImDto;
import com.yonyou.cyxdms.sysAuth.service.dto.PushDTO;
import com.yonyou.cyxdms.sysAuth.service.dto.notification.*;
import com.yonyou.cyxdms.sysAuth.service.entity.notification.*;
import com.yonyou.cyxdms.sysAuth.service.feign.FileServiceClient;
import com.yonyou.cyxdms.sysAuth.service.mapper.UserLoginMapper;
import com.yonyou.cyxdms.sysAuth.service.mapper.UserMapper;
import com.yonyou.cyxdms.sysAuth.service.mapper.notification.*;
import com.yonyou.cyxdms.sysAuth.service.service.Login.UserLoginService;
import com.yonyou.cyxdms.sysAuth.service.service.notification.NotificationService;
import com.yonyou.cyxdms.sysAuth.service.service.org.OrgService;
import com.yonyou.cyxdms.sysAuth.service.service.role.RoleService;
import com.yonyou.cyxdms.sysAuth.service.utill.BeanUtils;
import com.yonyou.cyxdms.sysAuth.service.vo.notification.AddNotificationVO;
import com.yonyou.cyxdms.sysmanage.client.domains.dto.ExtDTO;
import com.yonyou.cyxdms.sysmanage.client.domains.dto.ExtraDTO;
import com.yonyou.cyxdms.sysmanage.client.domains.dto.JPushDTO;
import com.yonyou.cyxdms.sysmanage.client.domains.dto.PushMsgDTO;
import com.yonyou.cyxdms.sysmanage.client.service.login.PushServices;
import com.yonyou.cyxdms.sysmanage.client.vo.role.UserbyRoleVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

//import com.yonyou.cms.proxy.service.fileupload.FileUploadInfoService;

/**
 * <p>
 * 通知通告信息表 服务实现类
 * </p>
 *
 * @author adu
 * @since 2019-10-14
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class NotificationServiceImpl extends ServiceImpl<NotificationMapper, NotificationPO> implements NotificationService {
    //日志对象
    private static final Logger logger = LoggerFactory.getLogger(NotificationServiceImpl.class);

    @Autowired
    HttpRequestService httpRequestService;
    @Autowired
    NotificationMapper notificationMapper;
    @Autowired
    public OrgService orgService;
    @Autowired
    NotificationDealerRoleMapper notificationDealerRoleMapper;
    @Autowired
    UserLoginService userLoginService;

    @Autowired
    NotificationDealerMapper notificationDealerMapper;

    @Autowired
    NotificationOemRoleMapper notificationOemRoleMapper;

    @Autowired
    PushServices pushService;
    @Autowired
    public UserMapper userMapper;

    @Autowired
    public UserLoginMapper userLoginMapper;

    @Autowired
    FileServiceClient fileServiceClient;

    @Value("${tm.url}")
    private String tmUrl;

    //   @Autowired
    //   FileUploadInfoService fileUploadInfoService;

    @Autowired
    NotificationFeedbackMapper notificationFeedbackMapper;

    //    @Autowired
//    EmployeeClientService employeeClientService;
    @Autowired
    private RoleService roleService;

    /**
     * 分页查询对应数据
     *
     * @param page           分页对象
     * @param queryCondition 查询条件
     * @return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map < java.lang.String, java.lang.Object>>
     * @author chengliang
     * @since 2019-09-11
     */
    @Override
    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    public IPage<Map<String, Object>> selectPageBysql(Page page, Map<String, Object> queryCondition) {
        // 获取总条数
        // this.formatDate(queryCondition);
        queryCondition.put("status", CommonConstants.PUBLISH);
        page.setRecords(notificationMapper.selectPageBySqls(page, queryCondition));
        return page;
    }

    /**
     * 查询
     *
     * @param page
     * @param queryCondition
     * @return
     */
    @Override
    public IPage<Map<String, Object>> getNoticeInfo(Page page, Map<String, Object> queryCondition) {
        // 获取总条数
        this.formatDate(queryCondition);
//       return page.setRecords(notificationMapper.getNoticeInfo(page, queryCondition));
        return page.setRecords(notificationMapper.getDealerNoticeInfo(page, queryCondition));
    }

    @Override
    public List<Map<String, Object>> getNoticeInfoNoRead(Map<String, Object> queryCondition) {
        return notificationMapper.getNoticeInfoNoRead(queryCondition);
    }


    @Override
    public IPage<Map<String, Object>> getNoticeInfos(Page page, Map<String, Object> queryCondition) {
        // 获取总条数
        this.formatDate(queryCondition);
        page.setRecords(notificationMapper.getNoticeInfos(page, queryCondition));
        return page;
    }

    @Override
    public IPage<Map<String, Object>> getNoticeJxsInfos(Page page, Map<String, Object> queryCondition) {
        // 获取总条数
        this.formatDate(queryCondition);
        // page.setRecords(notificationMapper.getNoticeJxsInfos(page, queryCondition));
        page.setRecords(notificationMapper.getNoticeDealerInfos(page, queryCondition));
        return page;
    }

    @Override
    public IPage<Map<String, Object>> getNoticeInfoIsRead(Page page, Map<String, Object> queryCondition) {
        // 获取总条数
        this.formatDate(queryCondition);
        page.setRecords(notificationMapper.getNoticeInfoIsRead(page, queryCondition));
        return page;
    }

    @Override
    public Integer getAlreadyIsRead(Integer notificationId) {
        return notificationMapper.getAlreadyIsRead(notificationId);
    }

    @Override
    public Integer getAlreadyNoRead(Integer notificationId) {
        return notificationMapper.getAlreadyNoRead(notificationId);
    }

    /**
     * 根据查询条件返回结果集
     *
     * @param queryCondition 查询条件
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author chengliang
     * @since 2019-09-11
     */
    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> selectListBySql(Map<String, Object> queryCondition) {
        return notificationMapper.selectListBySql(queryCondition);
    }

    /**
     * 根据查询条件返回结果集
     *
     * @param id 主键ID
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author chengliang
     * @since 2019-09-11
     */
    @Override
    @Transactional(readOnly = true)
    public Map<String, Object> getById(Long id) {
        NotificationPO notificationpo = notificationMapper.selectByIdss(id.intValue());
        if (notificationpo != null) {
            return notificationpo.toMaps();
        } else {
            throw new DALException("查询失败,没有符合条件的数据");
        }
    }

    /**
     * 根据DTO 进行数据新增
     *
     * @param notificationDTO 页面DTO
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author chengliang
     * @since 2019-09-11
     */
    @Override
    public Map<String, Object> insert(NotificationDTO notificationDTO) {
        //对对象进行赋值操作
        NotificationPO notificationpo = notificationDTO.transDtoToPo(NotificationPO.class);
        //执行插入
        notificationMapper.insert(notificationpo);
        //返回插入的值
        return notificationMapper.selectById(notificationpo.getNotificationId()).toMaps();
    }

    /**
     * 根据DTO 及ID 进行数据更新
     *
     * @param id              主键ID
     * @param notificationDTO 页面DTO
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author chengliang
     * @since 2019-09-11
     */
    @Override
    public Map<String, Object> update(Long id, NotificationDTO notificationDTO) {
        NotificationPO notificationpo = notificationMapper.selectById(id);
        //对对象进行赋值操作
        notificationDTO.transDtoToPo(notificationpo);
        //执行更新
        notificationMapper.updateById(notificationpo);
        return notificationpo.toMaps();
    }

    /**
     * 根据ID 进行删除数据
     *
     * @param id
     * @return void
     * @author chengliang
     * @since 2019-09-11
     */
    @Override
    public void deleteById(Long id) {
        int deleteCount = notificationMapper.deleteById(id);
        logger.debug("删除数量：{}", deleteCount);
        if (deleteCount <= 0) {
            throw new DALException("删除失败,没有符合条件的数据");
        }
    }

    /**
     * 根据ids 进行删除
     *
     * @param ids
     * @return void
     * @author chengliang
     * @since 2019-09-11
     */
    @Override
    public void deleteBatchIds(String ids) {
        List<Long> longList = StringUtils.convertStrToArray(ids, ",", Long.class);
        int deleteCount = notificationMapper.deleteBatchIds(longList);
        logger.debug("删除数量：{}", deleteCount);
        if (deleteCount != longList.size()) {
            throw new DALException("删除失败,没有符合条件的数据");
        }
    }

    /**
     * 通知通告数据保存
     *
     * @param notificationInfoDTO
     * @return
     */
    @Override
    public Integer insert(NotificationInfoDTO notificationInfoDTO, Integer... status) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        notificationInfoDTO.setPublishPerson(loginInfoDto.getUserName());
        notificationInfoDTO.setAppId(loginInfoDto.getAppId());
        notificationInfoDTO.setDataType(loginInfoDto.getDataType());
        notificationInfoDTO.setOrgId(loginInfoDto.getOrgId().intValue());
        //step1 保存主表数据
        Integer notificationId = this.insertNotification(notificationInfoDTO, status);

        List<NotificationDealerRoleListDTO> listDealerRole = notificationInfoDTO.getListDealerRole();
        List<NotificationDealerListDTO> listDealer = notificationInfoDTO.getListDealer();
        List<NotificationOemRoleListDTO> listOemRole = notificationInfoDTO.getListOemRole();
        //step2 保存下发的经销商角色数据(包含经销商（必须勾选）)
        if (null != listDealerRole && 0 != listDealerRole.size()) {
            //step3 保存下发的经销商数据（厂端必须勾选）
            List<String> ownerCode = new ArrayList<>();
            if (null != listDealer && 0 != listDealer.size()) {
                this.insertListDealer(notificationInfoDTO, notificationId);
                for (NotificationDealerListDTO a : listDealer) {
                    ownerCode.add(a.getOwnerCode());
                }
                logger.info("下发的经销商数据" + ownerCode.toString());
            } else {
                ownerCode.add(loginInfoDto.getOwnerCode());//店端经销商
            }
            this.insertListDealerRole(notificationInfoDTO, notificationId);
        }

        //step4 保存下发的车厂角色数据
        if (null != listOemRole && 0 != listOemRole.size()) {
            this.insertListOemRole(notificationInfoDTO, notificationId);
        }

        try {
            //step5  调用推送公告
            if (notificationInfoDTO.getStatus().equals(CommonConstants.PUBLISH)) {
                List<String> userIds;
                if (loginInfoDto.getDataType() == 10461003) {
                    if (notificationInfoDTO.getIsAll() == 10041001) {
                        userIds = notificationMapper.findNeedAllPushUserIds(loginInfoDto.getAppId());
                    } else {
                        userIds = notificationMapper.findNeedNotAllPushUserIds(notificationId);
                    }
                } else {
                    userIds = notificationMapper.findNeedDealerPushUserIds(notificationId, loginInfoDto.getCompanyId());
                }
                this.getPushMessage(notificationId, notificationInfoDTO, userIds);
            }
        } catch (Exception e) {
            logger.error("未找到可发布人");
        }
        return notificationId;
    }


    @Override
    public NotificationInfoDTO getNotificationInfoById(Integer notificationId) {

        //step1 获取主表数据
        NotificationInfoDTO notificationInfoDTO = this.getNotificationMain(notificationId);

        //step2 获取车场角色数据
        List<NotificationOemRoleListDTO> notificationOemRole = this.getNotificationOemRole(notificationId);
        if (notificationOemRole.size() != 0) {
            notificationInfoDTO.setListOemRole(notificationOemRole);
        }

        //step3 获取经销商信息
        List<NotificationDealerListDTO> notificationDealer = this.getNotificationDealer(notificationId);
        if (notificationDealer.size() != 0) {
            notificationInfoDTO.setListDealer(notificationDealer);
        }

        //step4 获取经销商角色类别信息
        List<NotificationDealerRoleListDTO> notificationDealerRole = this.getNotificationDealerRole(notificationId);
        if (notificationDealerRole.size() != 0) {
            notificationInfoDTO.setListDealerRole(notificationDealerRole);
        }
        //step5 获取附件信息
        // notificationInfoDTO.setFileUrl(this.getNotificationUrl(notificationId));

        return notificationInfoDTO;
    }

    @Override
    public Integer updateNotification(Integer notificationId, NotificationInfoDTO notificationInfoDTO, Integer... status) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        notificationInfoDTO.setPublishPerson(loginInfoDto.getUserName());
        notificationInfoDTO.setAppId(loginInfoDto.getAppId());
        notificationInfoDTO.setDataType(loginInfoDto.getDataType());
        notificationInfoDTO.setOrgId(loginInfoDto.getUserId().intValue());
        List<NotificationDealerRoleListDTO> listDealerRole = notificationInfoDTO.getListDealerRole();
        List<NotificationDealerListDTO> listDealer = notificationInfoDTO.getListDealer();
        List<NotificationOemRoleListDTO> listOemRole = notificationInfoDTO.getListOemRole();
        //step1 修改主表数据
        Integer id = this.updateNotificationMain(notificationId, notificationInfoDTO, status);

        //step2 修改车场角色数据
        if (null != listOemRole && 0 != listOemRole.size()) {
            this.updateNotificationOemRole(notificationId, notificationInfoDTO);
        }

        //step4 修改经销商角色数据
        if (null != listDealerRole && 0 != listDealerRole.size()) {
            //step3 修改经销商数据
            //List<String> ownerCode = new ArrayList<>();
            if (null != listDealer && 0 != listDealer.size()) {
                this.updateNotificationDealer(notificationId, notificationInfoDTO);
                this.updateNotificationDealerRole(notificationId, notificationInfoDTO);
            }
        }
        //step5  调用推送公告
        if (notificationInfoDTO.getStatus().equals(CommonConstants.PUBLISH)) {
            try {
                List<String> userIds;
                if (loginInfoDto.getDataType() == 10461003) {
                    if (notificationInfoDTO.getIsAll() == 10041001) {
                        userIds = notificationMapper.findNeedAllPushUserIds(loginInfoDto.getAppId());
                    } else {
                        userIds = notificationMapper.findNeedNotAllPushUserIds(notificationId);
                    }
                } else {
                    userIds = notificationMapper.findNeedDealerPushUserIds(notificationId, loginInfoDto.getCompanyId());
                }
                this.getPushMessage(notificationId, notificationInfoDTO, userIds);
            } catch (Exception e) {
                logger.error("没有可推送人", e);
            }
        }

        return id;
    }

    @Override
    public Integer withdrawNotificationByIds(List<Long> ids) {
        // step1 修改通知通告数据为已下发
        this.withdrawNotificaion(ids);

        this.deleteWithdrawUser(ids);

        return ids.size();
    }

    @Override
    public Long publishNotification(Integer id, NotificationInfoDTO notificationInfoDTO) {
        long notificationId;
        // step1 保存通知通告数据
        if (id == CommonConstants.UPDATE) {
            notificationId = this.insert(notificationInfoDTO, CommonConstants.PUBLISH);
        } else {
            NotificationPO notificationpo = notificationMapper.selectById(id);
            BeanMapperUtil.copyProperties(notificationpo, notificationInfoDTO);
            notificationId = this.updateNotification(id, notificationInfoDTO, CommonConstants.PUBLISH);
        }
       /*== List<NotificationOemRoleListDTO> listOemRole = notificationInfoDTO.getListOemRole();
        List<Long> ids = new ArrayList<>();
        ids.add(Long.valueOf(id));
        // 下发前先清空数据
        this.deleteWithdrawUser(ids);
        // step 2-1 通过RoleCode与componyId获取所有的用户信息 并创建一条记录- 厂端
        if (null != listOemRole) {
            long oemNum = this.createOemItem(listOemRole, notificationId);
            // step 2-2 通过codeId与componyIds 字符串信息获取所有的用户信息 -店端
            long dealerNum = this.createDealerItem(notificationInfoDTO, notificationId);
            return oemNum + dealerNum;
        }*/

        return notificationId;
    }

    @Override
    public List<Map<String, Object>> getIsReadList(Integer id, Long companyId) {
        return notificationMapper.getIsReadList(id, companyId);
    }

    @Override
    public  Page<Map<String, Object>> getCcNoReadList(Page<Map<String, Object>> page,
                                                                  Integer id, String appId, Long companyId) {
        return page.setRecords( notificationMapper.getCcNoReadList(page,id, companyId));
    }

    @Override
    public  Page<Map<String, Object>> getCcNoReadDealerList(Page<Map<String, Object>> page,
                                                                  Integer id, String appId, Long companyId) {
        return page.setRecords(notificationMapper.getCcDealerNoReadList(page,id, appId, companyId));
    }

    @Override
    public List<Map<String, Object>> getJxsNoReadList(Integer dataType, Integer id, String appId) {
        return notificationMapper.getJxsNoReadList(dataType, id, appId);
    }

    @Override
    public List<Map<String, Object>> getNoReadList(Integer id, Long companyId) {
        return notificationMapper.getNoReadList(id, companyId);
    }

    @Override
    public Integer getByStatusId(Long id) {
        LoginInfoDto loginInfo = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        return notificationMapper.getByStatusId(CommonConstants.PUBLISH, id, loginInfo.getAppId());
    }

    @Override
    public void addNotification(AddNotificationVO addNotificationVO) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        // loginInfoDto.get
        NotificationPO notificationpo = BeanMapperUtil.copyProperties(addNotificationVO, NotificationPO.class);
        // notificationPO.set
    }

    //获取厂端已读列表
    @Override
    public Page<Map<String, Object>> getCcIsReadList(Page<Map<String, Object>> page,Integer id, String appId, Long companyId) {
        return page.setRecords(notificationMapper.getCcIsReadList(page,id, appId, companyId));
    }

    //获取厂端已读列表
    @Override
    public Page<Map<String, Object>> getCcDealerIsReadList(Page<Map<String, Object>> page,Integer id, String appId, Long companyId) {
        return page.setRecords(notificationMapper.getCcDealerIsReadList(page,id,appId, companyId));
    }


    //时间戳转换date
    public static String timeStamp2Date(String seconds, String format) {
        if (seconds == null || seconds.isEmpty() || "null".equals(seconds)) {
            return "";
        }
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(seconds)));
    }

    //step2 保存下发的经销商角色数据
    private void insertListDealerRole(NotificationInfoDTO notificationInfoDTO, Integer notificationId) {
        //step2-1 将listDTO 封装为 listPO
        List<NotificationDealerRolePO> listRolePo = this.translistroledtotopo(notificationInfoDTO.getListDealerRole());

        for (NotificationDealerRolePO rolepo : listRolePo) {
            rolepo.setNotificationId(Long.valueOf(notificationId));
            notificationDealerRoleMapper.insert(rolepo);

        }
    }

    //step2-1 将listDTO 封装为 listPO
    private List<NotificationDealerRolePO> translistroledtotopo(List<NotificationDealerRoleListDTO> listDealerRoleDTO) {
        List<NotificationDealerRolePO> listDealerROlePo = new ArrayList<>();
        if (listDealerRoleDTO != null && listDealerRoleDTO.size() > 0) {
            BeanUtils.copyProperties(listDealerRoleDTO, listDealerROlePo, NotificationDealerRolePO.class);
        }
        return listDealerROlePo;
    }

    //step3 保存下发的经销商数据
    private void insertListDealer(NotificationInfoDTO notificationInfoDTO, Integer notificationId) {
        //step3-1 将listDTO 封装为 listPO
        List<NotificationDealerPO> listdealerpo = this.translistdealerdtotopo(notificationInfoDTO.getListDealer());

        for (NotificationDealerPO dealerpo : listdealerpo) {
            dealerpo.setNotificationId(Long.valueOf(notificationId));
            notificationDealerMapper.insert(dealerpo);
        }
    }

    //step3-1 将listDTO 封装为 listPO
    private List<NotificationDealerPO> translistdealerdtotopo(List<NotificationDealerListDTO> listDealerDTO) {
        List<NotificationDealerPO> listDealerPO = new ArrayList<>();
        if (listDealerDTO != null && listDealerDTO.size() > 0) {
            BeanUtils.copyProperties(listDealerDTO, listDealerPO, NotificationDealerPO.class);
        }
        return listDealerPO;
    }

    //step4 保存下发的车厂角色数据
    private void insertListOemRole(NotificationInfoDTO notificationInfoDTO, Integer notificationId) {
        //step2-1 将listDTO 封装为 listPO
        List<NotificationOemRolePO> listOemRolePo = this.transoemlistroledtotopo(notificationInfoDTO.getListOemRole());

        for (NotificationOemRolePO oemrolepo : listOemRolePo) {
            oemrolepo.setNotificationId(Long.valueOf(notificationId));
            notificationOemRoleMapper.insert(oemrolepo);
        }
    }

    //step4-1 将listDTO 封装为 listPO
    private List<NotificationOemRolePO> transoemlistroledtotopo(List<NotificationOemRoleListDTO> listOemRoleDTO) {
        List<NotificationOemRolePO> listOemRolePo = new ArrayList<>();
        if (listOemRoleDTO != null && listOemRoleDTO.size() > 0) {
            BeanUtils.copyProperties(listOemRoleDTO, listOemRolePo, NotificationOemRolePO.class);
        }
        return listOemRolePo;
    }

    //step5 保存附件 TODO 没存名称
    private void insertNotifictionUrl(NotificationInfoDTO notificationInfoDTO, Integer notificationId) {
        //fileUploadInfoService.insertFiles(notificationId, CommonConstants.NOTIFICATION_FILE,notificationInfoDTO.getFileUrl());
        RestResultResponse<String> upload = new RestResultResponse<>();
        upload.setResultCode(CommonConstants.NOTIFICATION_FILE);
        upload.setElapsedMilliseconds(notificationId);
        upload.setData(notificationInfoDTO.getFileUrl());
        fileServiceClient.upload(upload.toString());
    }

    // 给结束时间添加一天
    private void formatDate(Map<String, Object> queryCondition) {
        Object publisEndDate = queryCondition.get("publisEndDate");
        if (publisEndDate == null) {
            return;
        }
        String endDate = DateUtil.dateStrAddDay(publisEndDate.toString(), 1, "yyyy-MM-dd");
        queryCondition.put("publisEndDate", endDate);
    }

    // step1 获取通知通告主表数据
    private NotificationInfoDTO getNotificationMain(long notificationId) {
        return notificationMapper.getNotificationMain(notificationId);
    }

    // step2 获取车场角色数据
    private List<NotificationOemRoleListDTO> getNotificationOemRole(Integer notificationId) {
        return notificationOemRoleMapper.getOemRoleInfoListById(notificationId, CommonConstants.IS_NO);
    }

    // step3 获取经销商角色 TODO 事业部没翻译
    private List<NotificationDealerListDTO> getNotificationDealer(Integer notificationId) {
        return notificationDealerMapper.getNotificationDealer(notificationId, CommonConstants.IS_NO);
    }

    //step4 获取经销商角色类别信息
    private List<NotificationDealerRoleListDTO> getNotificationDealerRole(Integer notificationId) {
        return notificationDealerRoleMapper.getNotificationDealerRole(notificationId, CommonConstants.IS_NO);
    }

    //step5 获取附件信息
    private List<String> getNotificationUrl(Integer notificationId) {
        // List<Map<String, Object>> maps = fileUploadInfoService.selectListByBill(notificationId, CommonConstants.NOTIFICATION_FILE);
        RestResultResponse<String> upload = null;

        List<String> listUrl = new ArrayList<>();
//        for(Map<String,Object> map : maps){
//            listUrl.add(map.get("fileId").toString());
//        }
        return listUrl;
    }

    //step1 保存通知通告业务主表数据
    private Integer insertNotification(NotificationInfoDTO notificationInfoDTO, Integer... status) {
        //查找发布人角色的数据来源
        NotificationPO notificationpo = new NotificationPO();
        notificationInfoDTO.transDtoToPo(notificationpo);
        if (status == null || status.length == 0) {
            notificationpo.setStatus(CommonConstants.SAVE);
        } else {
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            notificationpo.setPublishDate(sf.format(System.currentTimeMillis()));
            notificationpo.setStatus(notificationInfoDTO.getStatus());
        }
        notificationMapper.insert(notificationpo);

        return notificationpo.getNotificationId().intValue();
    }

    //step1 修改主表数据
    private Integer updateNotificationMain(Integer id, NotificationInfoDTO notificationInfoDTO, Integer... status) {
        NotificationPO notificationpo = notificationMapper.selectById(id);
        notificationInfoDTO.transDtoToPoforIngore(notificationpo, CommonConstants.INGORE_PROPERTIES);
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (status == null || status.length == 0) {
            notificationpo.setStatus(CommonConstants.SAVE);
        } else {
            notificationpo.setStatus(CommonConstants.PUBLISH);
            notificationpo.setPublishPerson(notificationInfoDTO.getPublishPerson());
            notificationpo.setPublishDate(sf.format(System.currentTimeMillis()));
        }

        notificationMapper.updateById(notificationpo);
        return notificationpo.getNotificationId().intValue();
    }

    //step2 修改车场角色数据
    private void updateNotificationOemRole(Integer notificationId, NotificationInfoDTO notificationInfoDTO) {
        List<NotificationOemRoleListDTO> notificationOemRoleListDTO = this.getNotificationOemRole(notificationId);

        // step2-1 删除所有车厂角色
        this.deleteNotificationOemRole(notificationOemRoleListDTO);

        // step2-2 重新插入数据
        this.insertListOemRole(notificationInfoDTO, notificationId);

    }

    // step2-1 删除所有车场角色
    private void deleteNotificationOemRole(List<NotificationOemRoleListDTO> notificationOemRoleListDTO) {
        List<Long> ids = new ArrayList<>();
        for (NotificationOemRoleListDTO oemRoleListDTO : notificationOemRoleListDTO) {
            ids.add(oemRoleListDTO.getNotificationOemRoleId());
        }
        if (ids.size() - 0 == 0) {
            return;
        }
        notificationOemRoleMapper.deleteBatchIds(ids);
    }

    //step3 修改经销商数据
    private void updateNotificationDealer(Integer notificationId, NotificationInfoDTO notificationInfoDTO) {
        List<NotificationDealerListDTO> notificationDealer = this.getNotificationDealer(notificationId);

        // step3-1 删除所有的经销商数据
        this.deleteNotificationDealer(notificationDealer);

        // step3-2 重新插入数据
        this.insertListDealer(notificationInfoDTO, notificationId);

    }

    // step3-1 删除所有的经销商数据
    private void deleteNotificationDealer(List<NotificationDealerListDTO> notificationDealer) {
        List<Long> ids = new ArrayList<>();
        for (NotificationDealerListDTO notificationDealerListDTO : notificationDealer) {
            ids.add(notificationDealerListDTO.getNotificationDealerId());
        }
        if (ids.size() - 0 == 0) {
            return;
        }
        notificationDealerMapper.deleteBatchIds(ids);
    }

    //step4 修改经销商角色数据
    private void updateNotificationDealerRole(Integer notificationId, NotificationInfoDTO notificationInfoDTO) {
        List<NotificationDealerRoleListDTO> notificationDealerRole = this.getNotificationDealerRole(notificationId);

        // step4-1 删除所有的经销商角色类别数据
        this.deleteNotificationDealerRole(notificationDealerRole);

        // step4-2 重新插入数据
        this.insertListDealerRole(notificationInfoDTO, notificationId);
    }

    // step4-1 删除所有的经销商角色类别数据
    private void deleteNotificationDealerRole(List<NotificationDealerRoleListDTO> notificationDealerRole) {
        List<Long> ids = new ArrayList<>();
        for (NotificationDealerRoleListDTO notificationDealerRoleListDTO : notificationDealerRole) {
            ids.add(notificationDealerRoleListDTO.getNotificationDealerRoleId());
        }
        if (ids.size() - 0 == 0) {
            return;
        }
        notificationDealerRoleMapper.deleteBatchIds(ids);
    }

    // step1 通过IDs修改通知通告状态
    private void withdrawNotificaion(List<Long> ids) {
        for (Long notificationId : ids) {
            this.withdrawNotificaionById(notificationId, CommonConstants.WITHDRA);
        }
    }

    // step1 通过ID修改通知通告状态
    private void withdrawNotificaionById(Long notificationId, Integer status) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        notificationMapper.withdrawNotificaion(notificationId, CommonConstants.IS_NO, status, loginInfoDto.getUserId());
    }

    // step2 删除已经下发人关系
    private void deleteWithdrawUser(List<Long> ids) {
        notificationFeedbackMapper.deleteWithdrawUser(ids, CommonConstants.IS_NO);
    }

    // step 2-1 通过RoleCode与componyId获取所有的用户信息 并创建一条记录- 厂端
    private long createOemItem(List<NotificationOemRoleListDTO> listOemRole, long notificationId) {
        if (listOemRole == null) {
            return 0;
        }
        // step1 获取所有用户
        List<NotificationFeedbackPO> feedbackpolist = this.getOemUser(listOemRole, notificationId);
        this.insertFeedback(feedbackpolist);

        return feedbackpolist.size();
    }

    // setp2 插入数据到反馈表中
    private void insertFeedback(List<NotificationFeedbackPO> feedbackpolist) {
        if (feedbackpolist == null) {
            return;
        }
        for (NotificationFeedbackPO notificationfeedbackpo : feedbackpolist) {
            notificationFeedbackMapper.insert(notificationfeedbackpo);
        }
    }

    // step1 获取所有用户
    private List<NotificationFeedbackPO> getOemUser(List<NotificationOemRoleListDTO> listOemRole, long notificationId) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);

        StringBuffer ids = new StringBuffer();
        for (NotificationOemRoleListDTO notificationOemRoleListDTO : listOemRole) {
            ids.append(notificationOemRoleListDTO.getRoleCode()).append(",");
        }
        if (listOemRole.size() == 0) {
            return new ArrayList<>();
        }
        ids.substring(0, ids.length() - 1);

        // 获取用户
        List<UserbyRoleVO> userInfoByRole = roleService.getUserInfoByRole(ids.toString(), loginInfoDto.getCompanyId().toString());
        //  List<UserbyRoleVO> userInfoByRole =notificationFeedbackMapper.getUserInfoByRole(ids.toString(), loginInfoDto.getCompanyId().toString());

        // step NotificationFeedbackPO 封装
        return this.packageNotificationFeedbackPo(userInfoByRole, notificationId);
    }

    // step 2-2 通过codeId与componyIds 字符串信息获取所有的用户信息 -店端
    private long createDealerItem(NotificationInfoDTO notificationInfoDTO, long notificationId) {
        List<NotificationFeedbackPO> feedbackpolist;

        // step1 判断是否全网下发
        if (notificationInfoDTO.getIsAll() - CommonConstants.ALL == 0) {
            if (notificationInfoDTO.getListDealerRole() == null) {
                return 0;
            }
            // 是全网下发
            feedbackpolist = this.publishAll(notificationInfoDTO.getListDealerRole(), notificationId);
        } else {
            if (notificationInfoDTO.getListDealer() == null) {
                return 0;
            }
            // 非全网下发
            feedbackpolist = this.publishNoAll(notificationInfoDTO, notificationId);
        }
        // step2 插入数据
        this.insertFeedback(feedbackpolist);

        return feedbackpolist.size();
    }

    // 是全网下发
    private List<NotificationFeedbackPO> publishAll(List<NotificationDealerRoleListDTO> listDealerRole, long notificationId) {
        String codeIds = this.getCodeIds(listDealerRole);
        List<UserbyRoleVO> userInfoByRolePosition = roleService.getUserInfoByRolePosition(codeIds, null, null);
        return this.packageNotificationFeedbackPo(userInfoByRolePosition, notificationId);
    }

    // 非全网下发
    private List<NotificationFeedbackPO> publishNoAll(NotificationInfoDTO notificationInfoDTO, long notificationId) {
        String codeIds = this.getCodeIds(notificationInfoDTO.getListDealerRole());
        String componyIds = this.getComponyIds(notificationInfoDTO.getListDealer());
        List<UserbyRoleVO> userInfoByRolePosition = roleService.getUserInfoByRolePosition(codeIds, componyIds, null);
        return this.packageNotificationFeedbackPo(userInfoByRolePosition, notificationId);
    }

    // 获取code_ids
    private String getCodeIds(List<NotificationDealerRoleListDTO> listDealerRole) {
        StringBuffer ids = new StringBuffer();
        for (NotificationDealerRoleListDTO notificationDealerRoleListDTO : listDealerRole) {
            ids.append(notificationDealerRoleListDTO.getCodeId()).append(",");
        }
        if (listDealerRole.size() == 0) {
            return null;
        }
        ids.substring(0, ids.length() - 1);
        return ids.toString();
    }

    // 获取ComponyIds
    private String getComponyIds(List<NotificationDealerListDTO> listDealer) {
        StringBuffer ids = new StringBuffer();
        for (NotificationDealerListDTO notificationDealerListDTO : listDealer) {
            ids.append(notificationDealerListDTO.getDealerCompanyId()).append(",");
        }
        if (listDealer.size() == 0) {
            return null;
        }
        ids.substring(0, ids.length() - 1);
        return ids.toString();
    }

    // step NotificationFeedbackPO 封装
    private List<NotificationFeedbackPO> packageNotificationFeedbackPo(List<UserbyRoleVO> userInfoByRole, long notificationId) {
        List<NotificationFeedbackPO> notificationfeedbackpolist = new ArrayList<>();
        for (UserbyRoleVO userbyRoleVO : userInfoByRole) {
            NotificationFeedbackPO po = new NotificationFeedbackPO();
            po.setFeedbackUserName(userbyRoleVO.getEmployeeName());
            po.setFeedbackUser(userbyRoleVO.getUserId());
            // TODO 差一个发布时间
            po.setIsDealer(CommonConstants.IS_NO);
            po.setStatus(CommonConstants.NO_READ);
            po.setNotificationId(notificationId);
            notificationfeedbackpolist.add(po);
        }
        return notificationfeedbackpolist;
    }

    /**
     * 公告推送
     */
    @Override
    public void getPushMessage(Integer notificationId, NotificationInfoDTO notificationInfoDTO, List<String> userIds) {
        PushMsgDTO pushMsgDTO = new PushMsgDTO();
        pushMsgDTO.setContent("您有一条新的消息");
        pushMsgDTO.setUsers(userIds);
        pushMsgDTO.setMode("notify");
        pushMsgDTO.setTitle(notificationInfoDTO.getNotificationTitle());
        ExtraDTO extraDTO = new ExtraDTO();
        extraDTO.setAppRole(notificationInfoDTO.getDataType().intValue());
        extraDTO.setPushType(SysAuthCommonConstants.NOTICE_GG);
        extraDTO.setTzType("10461002");
        extraDTO.setKind(notificationId);
        extraDTO.setDateTime(System.currentTimeMillis());
        pushMsgDTO.setExtra(extraDTO);
        userLoginService.pushMsg(pushMsgDTO);
        logger.info("公告推送结束");
    }


    /**
     * 查询全网发布的用户
     */
    public String getUserIdByPush(PushDTO pushDTO, List<Object> stringObjectMap) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        logger.debug("消息推送开始:{}", pushDTO.toMaps());
        List<String> targetCodes = new ArrayList<String>();
        List<String> userIds1 = new ArrayList<String>();
        String appId = loginInfoDto.getAppId();
        if (null == stringObjectMap || 0 == stringObjectMap.size()) {
            throw new DALException("所选角色没有找到匹配的用户，请重新选择！");
        } else {
            if (stringObjectMap.get(0) == "-1") {  //-1全网发布
                List<Map<String, Object>> maps = userLoginMapper.setByUserId();
                String userId = null;
                for (Map<String, Object> a : maps) {
                    String regId = a.get("regId").toString().trim();
                    userId = a.get("userId").toString();
                    targetCodes.add(regId);
                    userIds1.add(userId);
                }
                this.tmCall(pushDTO, userIds1);//调用tm
            } else {
                if (null != stringObjectMap.get(0) && 0 != stringObjectMap.size()) {
                    // String[] userIds = stringObjectMap.get("userId").toString().split(",");
                    for (Object userId : stringObjectMap) {
                        userIds1.add(userId.toString());
                        //  String regId = userLoginMapper.selectRegIdByUserId(userId, "");//
                    }
                    logger.info("开始公告推送的用户》：{} " + userIds1.toString());
                    this.tmCall(pushDTO, userIds1);//调用tm
                    String regId = userLoginMapper.selectRegIdByUserIds(userIds1);
                    if (StringUtils.isNullOrEmpty(regId)) {
                        throw new DALException("该用户没有找到匹配RegId，请重新选择！");
                    }
                    String[] regIds = regId.split(",");
                    if (!StringUtils.isNullOrEmpty(regIds)) {
                        for (String rId : regIds) {
                            targetCodes.add(rId);
                        }
                        logger.info("推送的用户regId》：{} " + regId.toString());
                    } else {
                        throw new DALException("所选角色没有找到匹配的用户，请重新选择！");
                    }
                } else {
                    throw new DALException("所选角色没有找到匹配的用户，请重新选择！");
                }
            }
            if (!StringUtils.isNullOrEmpty(appId)) {
                loginInfoDto.setAppId(appId);
                logger.info("进入推送的appId为：{}" + appId);
            } else {
                throw new DALException("AppId不存在!");
            }
            JPushDTO jPushDTO = new JPushDTO();
            org.springframework.beans.BeanUtils.copyProperties(pushDTO, jPushDTO);
            jPushDTO.setTargetCodes(targetCodes);
            ExtDTO extDTO = new ExtDTO();
            Map<String, Object> platform = new HashMap<String, Object>();
            platform.put("platformSpecific", "");
            extDTO.setPlatform(platform);
            extDTO.setBusiness(pushDTO.getExtra());
            jPushDTO.setExt(extDTO);
            logger.info("公告推送开始：===============================" + jPushDTO.toString());
            String result = pushService.apps(jPushDTO,loginInfoDto.getAppId());
            logger.info("推送消息返回result：{}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            String resultCode = jsonObject.getString("code");
            logger.info("返回状态码：" + resultCode);
            if (!"200".equals(resultCode)) {
                String message = jsonObject.getString("error");
                logger.info("返回结果：" + message);
                throw new DMSAuthException(message);
            }
            return result;
        }
    }

    /**
     * tm推
     *
     * @param pushDTO
     * @param userIds
     */
    public void tmCall(PushDTO pushDTO, List<String> userIds) {
        logger.debug("进入TM调用=========================");
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        TextNotifyDto textNotifyDto = new TextNotifyDto();
        ExtraImDto extraImDto = new ExtraImDto();
        textNotifyDto.setAppId(loginInfoDto.getAppId());
        textNotifyDto.setPlatform("JMessage");
        textNotifyDto.setContent(pushDTO.getContent());
        textNotifyDto.setExtra(extraImDto);
        textNotifyDto.setToUsers(userIds);
        logger.debug("开始调用TM:{}", textNotifyDto.toString());
        publishNotificationIm(textNotifyDto);
    }


    /**
     * IM-通知
     *
     * @param textNotifyDto
     * @return
     */
    @Override
    public String publishNotificationIm(TextNotifyDto textNotifyDto) {
        logger.debug("TM:{}", textNotifyDto.toString());
        RestServiceRequestDto restServiceRequestDto = new RestServiceRequestDto();
        Map<String, String> headersParams = new HashMap<>();
        headersParams.put("appId", textNotifyDto.getAppId());
        restServiceRequestDto.setUrl(tmUrl);
        restServiceRequestDto.setHeadersParams(headersParams);
        restServiceRequestDto.setBody(textNotifyDto);
        RestServiceResponseDto restServiceResponseDto = httpRequestService.postJsonRequest(restServiceRequestDto);
        return restServiceResponseDto.getResponseMsg();
    }
}
